package pl.edu.agh.io.sylvia.logic;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;

import pl.edu.agh.io.sylvia.dao.ArticleDAO;
import pl.edu.agh.io.sylvia.dao.MonitorDAO;
import pl.edu.agh.io.sylvia.entity.Monitor;

public class NotificationDaemon implements Runnable {
	private Map<Monitor, Integer> articleDiff = new HashMap<Monitor, Integer>();
	private Map<Monitor, Date> timeDiff = new HashMap<Monitor, Date>();

	Logger log = Logger.getAnonymousLogger();

	public NotificationDaemon() {
		List<Monitor> monitors = new MonitorDAO().getAll();

		for (Monitor monitor : monitors) {
			timeDiff.put(monitor, new Date());
			articleDiff.put(monitor, 0);
		}
	}

	@Override
	public void run() {
		while (true) {
			List<Monitor> monitors = new MonitorDAO().getAll();

			for (Monitor monitor : monitors) {
				Calendar today = Calendar.getInstance();
				Calendar stored = Calendar.getInstance();

				if (monitor.getEmail() != null) {
					stored.setTime(timeDiff.get(monitor));
					int daysBetween = monitor.getHowOften();

					if ((today.get(Calendar.DAY_OF_YEAR) - stored
							.get(Calendar.DAY_OF_YEAR)) == daysBetween) {

						timeDiff.put(monitor, new Date());
						int nowArticles = new ArticleDAO().getByMonitorID(
								monitor.getId()).size();
						int previousArticles = articleDiff.get(monitor);

						if (sendMail(monitor, nowArticles - previousArticles)) {
							articleDiff.put(monitor, nowArticles);
						}

						timeDiff.put(monitor, new Date());
					}
				}
			}

			try {
				long oneDay = 24 * 60 * 60 * 1000;
				Thread.sleep(oneDay);
			} catch (InterruptedException e) {
				log.log(Level.SEVERE, e.getMessage(), e);
			}
		}

	}

	private boolean sendMail(Monitor monitor, int numOfArticles) {
		Properties smtpProperties = null;

		try {
			FileInputStream istream = new FileInputStream(
					"resources/smtp.properties");
			smtpProperties = new Properties();
			smtpProperties.load(istream);
			istream.close();
		} catch (IOException e1) {
			log.log(Level.SEVERE, e1.getMessage(), e1);
			return false;
		}

		try {
			SimpleEmail email = new SimpleEmail();
			String user = smtpProperties.getProperty("user");
			String password = smtpProperties.getProperty("password");

			if((user != null) && (password != null)) {
				email.setAuthentication(user, password);
			}
			email.setHostName(smtpProperties.getProperty("host"));
			email.addTo(monitor.getEmail(), monitor.getEmail());
			email.setFrom("sylvia@student.agh.edu.pl", "usenet");
			email.setSubject("Usenet messages report");
			email.setMsg("The number of new messages you have is: "
					+ numOfArticles);
			email.send();
		} catch (EmailException e) {
			log.log(Level.SEVERE, e.getMessage(), e);
			return false;
		}
		return true;
	}
}
